home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
ab20
/
ab20_archive
/
utilities
/
arexx
/
rexxarplib-2.52.lzh
/
rexx
/
graph.rexx
< prev
next >
Wrap
OS/2 REXX Batch file
|
1989-04-01
|
9KB
|
304 lines
/*
** g r a p h . r e x x
**
** This is a simple graphing function that plots functions passed to it.
** It determines upper and lower limits for the function in the range to
** be plotted, and scales the graph accordingly. It determines a reasonable
** scale division to use and draws a grid. Wait till it's done plotting and
** then fiddle the sizing gadget! Click on the close gadget to quit.
**
** Calling sequence:
**
** call graph(title, bins, xmin, xmax, function)
**
** Arguments:
**
** title The string to put at the bottom of the graph
** bins The number of horizontal samples to compute
** xmin The starting X value
** xmax The ending X value
** function The function to compute. The function must be of
** a single variable, x, and can otherwise only include
** math functions and numerical constants. Be careful
** and avoid specifying functions with singularities in
** the plotting range.
**
** Examples:
** title bins xmin xmax function
**
** call graph("exp(-x2)" , 50, -2.5, 2.5, "30. * exp(-(x**2))")
** call graph("x3 + 2x - 13", 25, -2.5, 2.5, "x**3 + 2*x - 13" )
** call graph("sin(x)" , 25, 0.0, 6.3, "45. * sin(x)" )
** call graph("log(x)" , 25, 0.01, 5.0, "45. * log(x)" )
**
** By W.G.J. Langeveld, march 1989.
*/
/* trace r */
parse arg tt, nn, xx, yy, ff
if ~show('l', "rexxarplib.library") then do
check = addlib('rexxsupport.library',0,-30,0)
check = addlib('rexxmathlib.library',0,-30,0)
check = addlib('rexxarplib.library',0,-30,0)
end
plot.bins = nn
plot.xmin = xx
plot.xmax = yy
plot.title = tt
delta = (plot.xmax - plot.xmin)/plot.bins
x = plot.xmin
do i = 0 to plot.bins
interpret "plot.i = "||ff
x = x + delta
end
/*
* Determine the max and min of the curve
*/
minval = plot.0
maxval = plot.0
do i = 1 to plot.bins
maxval = max(plot.i,maxval)
minval = min(plot.i,minval)
end
/*
* Initial window sizes
*/
window.leftedge = 50
window.topedge = 25
window.width = 300
window.height = 150
/*
* Set up a host.
*/
address command runwsh "'call CreateHost(GRAPHHOST, GRAPHPORT)'"
/*
* Wait for a while until host is ready.
*/
do 50 while ~show('Ports','GRAPHHOST')
call delay 10 /* 200 ms */
end
/*
* Open the window
*/
idcmp = 'CLOSEWINDOW+NEWSIZE'
flags = 'WINDOWCLOSE+WINDOWDRAG+WINDOWDEPTH+WINDOWSIZING'
call OpenWindow(GRAPHHOST, window.leftedge, window.topedge, window.width, ,
window.height, idcmp, flags)
/*
* Set NEWSIZE message to something useful
*/
call ModifyHost(GRAPHHOST, NEWSIZE, "%w %h")
/* Open our host port */
call openport(GRAPHPORT)
start:
/*
* Make a drawing area
*/
area.topedge = min(0.1, 20/window.height)
area.leftedge = min(0.2, 60/window.width)
area.width = 1.0 - 2 * area.leftedge
area.height = 1.0 - 3 * area.topedge
/*
* Draw the box outline of the plot
*/
call SetAPen(GRAPHHOST, 3)
call Move(GRAPHHOST, area.leftedge * window.width - 2, ,
area.topedge * window.height - 1)
call Draw(GRAPHHOST, area.leftedge * window.width - 2, ,
(area.topedge + area.height) * window.height + 1)
call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width + 2, ,
(area.topedge + area.height) * window.height + 1)
call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width + 2, ,
area.topedge * window.height - 1)
call Draw(GRAPHHOST, area.leftedge * window.width - 2, ,
area.topedge * window.height - 1)
/*
* Determine a nice grid to use. Try for 15 pixels heigh.
*/
vticks = (window.height * area.height) % 15
vscale = (maxval - minval) / vticks
if vscale < 1 then
do
do imults = 1 until vscale > 1
vscale = vscale * 10
end
vscale = nint(vscale * 2) / 2
/* do i = 1 to imults
vscale = vscale / 10
end */
vscale = vscale / 10**imults
end
else
do
do imults = 1 until vscale < 1
vscale = vscale / 10
end
vscale = vscale * 10
vscale = nint(vscale * 2) / 2
/* do i = 1 to imults - 1
vscale = vscale * 10
end */
vscale = vscale * 10**(imults-1)
end
/*
* ...and for 50 pixels wide
*/
hticks = (window.width * area.width) % 50
hscale = (plot.xmax - plot.xmin)/hticks
if hscale < 1 then
do
do imults = 1 until hscale > 1
hscale = hscale * 10
end
hscale = nint(hscale * 2) / 2
/* do i = 1 to imults
hscale = hscale / 10
end */
hscale = hscale * 10**(-imults)
end
else
do
do imults = 1 until hscale < 1
hscale = hscale / 10
end
hscale = hscale * 10
hscale = nint(hscale * 2) / 2
/* do i = 1 to imults - 1
hscale = hscale * 10
end */
hscale = hscale * 10**(imults-1)
end
/*
* Draw the grid and add scale text
*/
ys = (minval % vscale) * vscale
if ys < minval then ys = ys + vscale
do while ys <= maxval
level = (area.topedge + area.height * ,
(1.0 - (ys - minval) / (maxval - minval))) * window.height
call SetAPen(GRAPHHOST, 3)
call SetDrPt(GRAPHHOST, c2d('C3C3C3C3'x))
call Move(GRAPHHOST, area.leftedge * window.width, level)
call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width, level)
call SetAPen(GRAPHHOST, 1)
call SetDrPt(GRAPHHOST, c2d('FFFFFFFF'x))
call Move(GRAPHHOST, area.leftedge * window.width - 8 * length(ys) - 8, ,
level + 4)
call Text(GRAPHHOST, ys)
ys = ys + vscale
/* if ys > maxval then leave */
end
/* trace off */
xs = (plot.xmin % hscale) * hscale
if xs < plot.xmin then xs = xs + hscale
do while xs < plot.xmax
level = (area.leftedge + area.width * /* */ ,
((xs - plot.xmin) / (plot.xmax - plot.xmin))) * window.width
call SetAPen(GRAPHHOST, 3)
call SetDrPt(GRAPHHOST, c2d('C3C3C3C3'x))
call Move(GRAPHHOST, level, area.topedge * window.height)
call Draw(GRAPHHOST, level, (area.topedge + area.height) * window.height)
call SetAPen(GRAPHHOST, 1)
call SetDrPt(GRAPHHOST, c2d('FFFFFFFF'x))
call Move(GRAPHHOST, level - length(xs) * 4, /* */ ,
(area.topedge + area.height) * window.height + 10)
call Text(GRAPHHOST, xs)
xs = xs + hscale
/* if xs > plot.xmax then leave */
end
/*
* Draw the zero lines (if exist)
*/
if minval <= 0 & maxval > 0 then do
zerolevel = (area.topedge + area.height * ,
(1.0 + minval / (maxval - minval))) * window.height
call SetAPen(GRAPHHOST, 2)
call Move(GRAPHHOST, area.leftedge * window.width, zerolevel)
call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width, zerolevel)
end
if plot.xmin <= 0 & plot.xmax > 0 then
do
zerolevel = (area.leftedge - area.width * /* */ ,
(plot.xmin / (plot.xmax - plot.xmin))) * window.width
call SetAPen(GRAPHHOST, 2)
call Move(GRAPHHOST, zerolevel, area.topedge * window.height)
call Draw(GRAPHHOST, zerolevel, /* */ ,
(area.topedge + area.height) * window.height)
end
/*
* Plot the title
*/
call SetAPen(GRAPHHOST, 1)
call Move(GRAPHHOST, /* */ ,
(area.leftedge + area.width / 2) * window.width - length(plot.title) * 4, ,
0.5 * (1.0 + area.topedge + area.height) * window.height + 10)
call Text(GRAPHHOST, plot.title)
/*
* Draw the plot
*/
call SetAPen(GRAPHHOST, 1)
call Move(GRAPHHOST, area.leftedge * window.width, ,
(area.topedge + area.height * (1.0 - ,
(plot.0 - minval) / (maxval - minval))) * window.height)
do i = 0 to plot.bins
call Draw(GRAPHHOST, /* */ ,
(area.width * i / plot.bins + area.leftedge) * window.width, /* */ ,
(area.topedge + area.height * /* */ ,
(1.0 - (plot.i - minval) / (maxval - minval))) * window.height)
end
/*
* Wait for messages at GRAPHPORT
*/
quitflag = 0
do forever until quitflag
call waitpkt(GRAPHPORT)
p = getpkt(GRAPHPORT)
if p ~== NULL() then
do
thisarg = getarg(p)
t = reply(p, 0)
/*
* Messages are either CLOSEWINDOW
*/
if thisarg == 'CLOSEWINDOW' then do
call CloseWindow(GRAPHHOST)
quitflag = 1
end
/*
* ...or NEWSIZE
*/
else do
parse var thisarg xwidth xheight
window.width = (xwidth % 10) * 10
window.height = (xheight % 10) * 10
call SetReqColor(GRAPHHOST, BACK, 0L)
call BackFill(GRAPHHOST)
signal start /* start over */
end
end
end
exit